import cv2
import os
import matplotlib.pyplot as plt
import numpy as np

# 创建"char"文件夹（如果不存在）
if not os.path.exists('char'):
    os.makedirs('char')

img = cv2.imread('hanzi1.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = img[450:3950, 20:3000]
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_2 = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY_INV)[1]

kernel = np.ones((9, 9), np.uint8)

#开运算
opened_img = cv2.morphologyEx(img_2, cv2.MORPH_OPEN, kernel)
#闭运算
closed_img = cv2.morphologyEx(opened_img, cv2.MORPH_CLOSE, kernel, iterations=10)
#腐蚀操作
eroded_image = cv2.erode(img_2, kernel, iterations=1)
#膨胀操作
dilated_image = cv2.medianBlur(eroded_image, 3)  # 中值滤波去小白点
dilated_image = cv2.dilate(dilated_image, kernel, iterations=2)

# 使用 Canny 算子进行边缘检测
# 参数1：输入图像
# 参数2：较低的阈值
# 参数3：较高的阈值
# 这里需要提供上下阈值进行滞后阈值分割，阈值设置为100和200
lower = 100
upper = 200

#去噪
img_blur = cv2.GaussianBlur(closed_img,(5,5), 0)
edges_with_blur = cv2.Canny(img_blur, lower, upper)

# 得到图像轮廓列表
contours, _ = cv2.findContours(edges_with_blur, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

img_copy = img_rgb.copy()
# 遍历轮廓列表
print(len(contours))
i=1
for index, c in enumerate(contours):
    perimeter = cv2.arcLength(c, True)
    if perimeter > 100 and index % 2 !=0:
        x, y, w, h = cv2.boundingRect(c)
        cv2.rectangle(img_rgb, (x, y), (x + w, y + h), (0, 255, 0), 2)
        char_img = img_copy[y:y+h, x:x+w]  # 提取汉字图像
        char_filename = os.path.join('char', f'char_{i}.jpg')  # 生成文件名
        cv2.imwrite(char_filename, char_img)  # 保存汉字图像
        i=i+1


plt.imshow(img_rgb, cmap='gray')
plt.axis('off')
plt.savefig('biaoji.png', dpi=300)
plt.show()

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
fg, ax = plt.subplots(2, 3, figsize=(15, 5))
ax[0,0].imshow(img, cmap='gray')  # 在第一个子图中显示原图，使用灰度色彩映射
ax[0,0].set_title("原图灰度图")
ax[0,0].axis('off')

ax[0,1].imshow(img_2, cmap='gray')
ax[0,1].set_title("全局阈值处理>>二值化图")
ax[0,1].axis('off')

ax[0,2].imshow(eroded_image, cmap='gray')
ax[0,2].set_title("应用腐蚀操作>>去除噪点")
ax[0,2].axis('off')

ax[1,0].imshow(dilated_image, cmap='gray')
ax[1,0].set_title("应用膨胀操作>>突出图像特征>>中值滤波去除小白点")
ax[1,0].axis('off')

ax[1,1].imshow(closed_img, cmap='gray')
ax[1,1].set_title("应用闭运算>>填充闭合区域")
ax[1,1].axis('off')

ax[1,2].imshow(edges_with_blur, cmap='gray')
ax[1,2].set_title("Canney边缘检测")
ax[1,2].axis('off')

plt.tight_layout()
plt.savefig('output.png', dpi=300)
plt.show()


